function bindEventMousemove (self, { lastX, lastY, down, downX, downY }) {
  const { $scope } = self;

  window.onmousedown = function(ev) {
    option.down = true;
    option.downX = option.lastX = ev.clientX;
    option.downY = option.lastY = ev.clientY;
    self.cameraVelocity.multiplyScalar(0);
    option.clickActive = true;

    if (ev.preventDefault) {
      ev.preventDefault();
    }
  };

  listen(document.getElementById('overlays'), 'mousemove', function(ev) {
    self.mouseCurrent.clientX = ev.clientX;
    self.mouseCurrent.clientY = ev.clientY;
  });

  window.onmousemove = function(ev) {
    if (down) {
      var dy = ev.clientY - lastY;
      var dx = ev.clientX - lastX;
      self.cameraVelocity.z = (
        self.touchMode
          ? self.cameraVelocity.z/2 + (-dy/3)/2
          : self.cameraVelocity.z/2 + -dy
      );
      lastY = ev.clientY;
      lastX = ev.clientX;
      if (Math.abs(downY - lastY) > 5 || Math.abs(downX - lastX) > 5) {
        clickActive = false;
      }
      if (self.touchMode) {
        self.cameraVelocity.x = self.cameraVelocity.x/2 + (-4*dx / window.innerWidth)/2;
        if (dx*dx > dy*dy) {
          self.cameraVelocity.z = 0;
        } else {
          self.cameraVelocity.x = 0;
        }
        if (self.cameraXOffset > 1) {
          self.cameraXOffset = 1;
          self.cameraVelocity.x = 0;
        }
        if (self.cameraXOffset < -1) {
          self.cameraXOffset = -1;
          self.cameraVelocity.x = 0;
        }
      }
    } else if (ev.target === document.getElementById('overlays')) {
      var previousHovered = null;
      self.objects.blobs.children.forEach(function(c) {
        if (c.hovered) {
          previousHovered = c;
        }
        c.hovered = false;
      });
      var obj = self.findToolbarUnderEvent(ev);
      if (obj) {
        // $scope.hoveredGeography = obj.geographyName;
      } else {
        // $scope.hoveredGeography = null;
        obj = self.findObjectUnderEvent(ev);
        if (obj) {
          obj.hovered = true;
          if (obj !== previousHovered && (obj.soundLastPlayed == null || (Date.now() - obj.soundLastPlayed) > 200)) {
            obj.soundLastPlayed = Date.now()
            if (obj.soundIndex === undefined) {
              obj.soundIndex = -4*obj.position.y;
            }
            // self.audioManager.playSoundEffect(obj.soundIndex);
          }
        }
      }
    }
    var mouse3D = new THREE.Vector3(
      ( ev.clientX / self.width ) * 2 - 1,
      -( ev.clientY / self.height ) * 2 + 1,
      0.5
    );
    if (self.introTime > self.introLength) {
      self.cameraXOffset = self.touchMode ? self.cameraXOffset : mouse3D.x;
      self.cameraYOffset = self.touchMode ? (self.width > self.height ? 1 : 0.5) : mouse3D.y;
    }
    if (ev.preventDefault) {
      ev.preventDefault();
    }
  };
  window.onmouseup = function(ev) {
    option.down = false;
    self.cameraZMotion = 0;
    self.cameraZTarget = null;
    if (ev.preventDefault) {
      ev.preventDefault();
    }
    // console.log(ev.target);
    if (option.clickActive && ev.target === document.getElementById('overlays')) {
      var obj = self.findToolbarUnderEvent(ev);
      if (obj) {
        // if ($scope.selectedGeography === obj.geographyName) {
        //   $scope.selectedGeography = null;
        // } else {
        //   $scope.selectedGeography = obj.geographyName;
        // }
      } else {
        var obj = self.findObjectUnderEvent(ev);
        self.objects.blobs.children.forEach(function(c) {
          c.selected = false;
          c.connectionSelected = false;
        });
        var needDigest = false;
        if (obj) {
          obj.selected = true;
          // if (!$scope.categoryToggled && $scope.category !== obj.objectData.categoryName) {
          //   $scope.category = (obj.objectData.categoryName + '').toLowerCase();
          //   needDigest = true;
          // }
          obj.connections.forEach(function(c) {
            c.connectionSelected = true;
          });
        } // else if (!$scope.categoryToggled && $scope.category !== null) {
        //   $scope.category = null;
        //   needDigest = true;
        // }
        // if ($scope.hoverInfoObject !== obj) {
        //   $scope.hoverInfoObject = obj;
        //   needDigest = true;
        //   if (needDigest) {
        //     $scope.$digest();
        //   }
        //   if ($scope.hoverInfoObject) {
        //     var hoverInfoEl = document.getElementById('object-hover-info');
        //     if (ev.clientX + 480 > window.innerWidth && ev.clientX - 480 < 0) {
        //       hoverInfoEl.style.left = window.innerWidth/2 - 460/2 + 'px';
        //       hoverInfoEl.style.right = 'auto';
        //     } else if (ev.clientX + 460 > window.innerWidth) {
        //       hoverInfoEl.style.right = window.innerWidth - (ev.clientX - 50) + 'px';
        //       hoverInfoEl.style.left = 'auto';
        //     } else {
        //       hoverInfoEl.style.right = 'auto';
        //       hoverInfoEl.style.left = ev.clientX + 50 + 'px';
        //     }
        //     if (ev.clientY + 200 > window.innerHeight) {
        //       hoverInfoEl.style.top = 'auto';
        //       hoverInfoEl.style.bottom = window.innerHeight - (ev.clientY - 30) + 'px';
        //     } else {
        //       hoverInfoEl.style.bottom = 'auto';
        //       hoverInfoEl.style.top = ev.clientY + 30 + 'px';
        //     }
        //
        //     hoverInfoEl.style.backgroundColor = $scope.hoverInfoObject.objectData.backgroundColor;
        //   }
        // } else if (obj && $scope.hoverInfoObject === obj) {
        //   self.objects.blobs.children.forEach(function(c) {
        //     c.selected = false;
        //     c.connectionSelected = false;
        //   });
        // } else {
        //   // $scope.selectedGeography = null;
        // }
      }
    }
  };

  window.onmousewheel = function(ev) {
    if ($scope.introState < 4) {
      if (ev.wheelDelta < 0) {
        $scope.$digest();
      }
    } else if (self.introTime >= self.introLength + 16) {
      self.cameraZTarget = (
        self.cameraZTarget || self.camera.position.z
      ) - ev.wheelDelta * 0.15;
    }
  };
}
